﻿using LD.Host;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LD
{
    /// <summary>
    /// 电批帮助类
    /// </summary>
    public class ScrewHelper
    {
        //private static ScrewHelper instance;
        //private static object locker = new object();
        public delegate void ReceiveData(string name, TB_Screw screwData, List<ScrewDataModel> data);
        public event ReceiveData ReceiveDataEvent;
        private ManualResetEvent aManualReset = new ManualResetEvent(false);
        //public event EventHandler<TB_Screw> OnDataChanged;
        private object obj = new object();
        private bool m_aRegedit;
        private bool m_Start;
        private List<ScrewDataModel> A_ChartData;                   //电批原始数据
        private string m_Name;
        public ScrewHelper()
        {
            if (TcpIpService.Instance.CommuniDic.ContainsKey(Name))
            {
                TcpIpService.Instance[Name].ConnectionStateEvent += AConnectionStateEvent;
                TcpIpService.Instance[Name].OnMessageReceived += AScrewHelper_OnMessageReceived;
            }
        }
        public ScrewHelper(string name)
        {
            m_Name = name;
        }
        #region 属性
        public string Name
        {
            get { return m_Name; }
        }
        public TB_Screw A_Data { get; set; }
        #endregion

        private void AConnectionStateEvent(string name, Status status)
        {
            if (status == Status.成功)
            {
                if (!m_aRegedit)
                {
                    Regedit(name);
                }
            }
            else
                m_aRegedit = false;
        }
        private void AScrewHelper_OnMessageReceived(object sender, byte[] e)
        {
            if (m_aRegedit)
            {
                if (m_Start)
                {
                    A_ChartData?.Clear();
                    A_ChartData = new List<ScrewDataModel>();
                    A_ParseData(e);
                }
                else
                    LogHelper.Instance.Alarm("", "电批未收到启动信号,数据不接收");
            }
            else
                LogHelper.Instance.Alarm("", "电批未注册");
        }
        //public static ScrewHelper Instance
        //{
        //    get
        //    {
        //        if (instance == null)
        //        {
        //            lock (locker)
        //            {
        //                if (instance == null)
        //                    instance = new ScrewHelper();
        //            }
        //        }
        //        return instance;
        //    }
        //}
        public void Init()
        {

        }
        /// <summary>
        /// 开始拧螺丝
        /// </summary>
        public bool Start()
        {
            m_Start = true;
            aManualReset.Reset();

            //等待数据
            var result = aManualReset.WaitOne(10000);
            if (!result)
            {
                string error = $"【{Name}】电批等待数据时超时or网络中断";
                LogHelper.Instance.Alarm("", error);
                A_Data.Result = "FAIL";
                A_Data.Remark = error;
                return false;
            }
            return true;
        }
        /// <summary>
        /// 保存csv到本地
        /// </summary>
        public void Save()
        {
            string filePath = Path.Combine(Appbus.BasePath, "电批原始数据\\" + DateTime.Now.ToString("yyyy-MM-dd"));
            CreateDir(filePath);

            //保存excel
            string dataFileName = A_Data.Barcode + "_" + A_Data.Location + "_" + A_Data.Result + "_" + DateTime.Now.ToString("yyyyMMddHHmmssfff");
            ExcelHelper.Save(dataFileName, A_ChartData);

            A_Data.FileName = dataFileName;
            A_Data.FilePath = Path.Combine(filePath, dataFileName);

            ReceiveDataEvent?.Invoke(Name, A_Data, A_ChartData);
            //OnDataChanged?.Invoke(A_Data.PointName, A_Data);
            //save db
            DBHelper.Instance.Sql.Insertable(A_Data).ExecuteCommand();
        }
        public void ChangePart(string name, int id)
        {
            //转换为2进制驱动IO,最多7个机种
            List<string> _io = new List<string>();
            if (name == "B轨_电批")
                _io = new List<string>() { "B轨_电批程序0", "B轨_电批程序1", "B轨_电批程序2" };
            else
                _io = new List<string>() { "A轨_电批程序0", "A轨_电批程序1", "A轨_电批程序2" };

            var bin2 = Convert.ToString(id + 1, 2).PadLeft(3, '0').Reverse().ToArray();
            for (int i = 0; i < _io.Count; i++)
            {
            }

            Task.Delay(500).Wait();
        }
        public void Regedit(string name)
        {
            string cmd = "002000010060        ";
            TcpIpService.Instance[name].Send(cmd);

            cmd = "006000080010        1201001310000000000000000000000000000001";
            TcpIpService.Instance[name].Send(cmd);

            cmd = "006700080010        0900002380                             02001002";
            TcpIpService.Instance[name].Send(cmd);

        }
        private void A_ParseData(byte[] data)
        {
            string temp = Encoding.ASCII.GetString(data, 4, 4);
            switch (temp)
            {
                case "0002":
                    m_aRegedit = true;
                    break;
                case "1201":
                    Console.WriteLine("1201");
                    break;
                case "1202":
                    //PeakTorque字段
                    string allData = Encoding.ASCII.GetString(data);
                    int loc = allData.LastIndexOf("30230");
                    if (loc > 0)
                    {
                        string totalTorque = allData.Substring(loc + 12 + 5, 12);
                        Log4.Info($"【{m_Name}】截取扭矩数据:" + totalTorque);
                        double.TryParse(totalTorque, out var torque);
                        A_Data.PeakTorqueMax = Math.Round(torque, 6);
                    }
                    //TotalAngle字段
                    loc = allData.LastIndexOf("30231");
                    if (loc > 0)
                    {
                        string totalAngle = allData.Substring(loc + 12 + 5, 12);
                        Log4.Info($"【{m_Name}】截取角度数据:" + totalAngle);
                        double.TryParse(totalAngle, out var angle);
                        A_Data.Angle = angle;
                    }
                    //FinalTorque字段
                    loc = allData.LastIndexOf("30237");
                    if (loc > 0)
                    {
                        string totalAngle = allData.Substring(loc + 12 + 5, 12);
                        Log4.Info($"【{m_Name}】截取夹紧扭矩数据:" + totalAngle);
                        double.TryParse(totalAngle, out var torque_jiajin);
                        A_Data.Actual_Torque = torque_jiajin;
                    }
                    break;
                case "0900":
                    string pid = Encoding.ASCII.GetString(getPid(data));
                    string no = Encoding.ASCII.GetString(getNo(data));
                    string len = Encoding.ASCII.GetString(new byte[5] { data[146], data[147], data[148], data[149], data[150] });
                    if (Encoding.ASCII.GetString(new byte[2] { data[99], data[100] }) == "01")
                    {
                        var bytes = new byte[data.Length - 152];
                        Array.Copy(data, 152, bytes, 0, bytes.Length);
                        角度(no, A_ChartData, pid, bytes);
                        int.TryParse(no, out var _no);
                        A_Data.No = _no;
                    }
                    if (Encoding.ASCII.GetString(new byte[2] { data[99], data[100] }) == "02")
                    {
                        var bytes = new byte[data.Length - 152];
                        Array.Copy(data, 152, bytes, 0, bytes.Length);
                        扭矩(A_ChartData, pid, bytes);

                        //A_Data.扭矩Max = Math.Round(A_ChartData.Max(p => p.扭矩), 6);
                        aManualReset.Set();
                    }
                    Console.WriteLine("0900");
                    break;
                case "0901":
                    Console.WriteLine("0901");
                    break;
                default:
                    break;
            }
        }

        private void 角度(string no, List<ScrewDataModel> model, string pid, byte[] data)
        {
            double.TryParse(pid, out var _pid);

            for (int i = 0; i < data.Length; i += 2)
            {
                model.Add(new ScrewDataModel()
                {
                    序号 = no,
                    角度 = _pid * ToInt16(data, i)
                });
            }
        }
        private void 扭矩(List<ScrewDataModel> model, string pid, byte[] data)
        {
            double.TryParse(pid, out var _pid);
            int index = 0;
            for (int i = 0; i < data.Length; i += 2)
            {
                model[index].扭矩 = _pid * ToInt16(data, i) / 98;
                index++;
            }
        }
        private byte[] getPid(byte[] data)
        {
            byte[] pid = new byte[12];
            Array.Copy(data, 69, pid, 0, 12);
            return pid;
        }
        private byte[] getNo(byte[] data)
        {
            byte[] no = new byte[10];
            Array.Copy(data, 20, no, 0, 10);
            return no;
        }
        public static short ToInt16(byte[] value, int startIndex)
        {
            if (value == null)
            {
                return 0;
            }

            byte[] data = new byte[2];
            data[0] = value[startIndex];
            data[1] = value[startIndex + 1];
            short aa = BitConverter.ToInt16(data, 0);
            return BitConverter.ToInt16(data, 0);
        }
        private void CreateDir(string filePath)
        {
            lock (obj)
            {
                if (!Directory.Exists(filePath))
                    Directory.CreateDirectory(filePath);
            }
        }
    }
}
